package com.example.demo.demo.datatype;

import org.junit.Test;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;

/**
 * BigDecimal 使用
 *
 * 6.1、总结
 * 在需要精确的小数计算时再使用BigDecimal，BigDecimal的性能比double和float差，在处理庞大，
 * 复杂的运算时尤为明显。故一般精度的计算没必要使用BigDecimal。尽量使用参数类型为String的构造函数。
 *
 * BigDecimal都是不可变的（immutable）的， 在进行每一次四则运算时，都会产生一个新的对象 ，
 * 所以在做加减乘除运算时要记得要保存操作后的值
 *
 * @author Roger
 * @since 2021/7/24
 */
public class BigDecimalTest {

    /**
     * 构造方法
     */
    public void constructor(){
        //BigDecimal(int) 创建一个具有参数所指定整数值的对象
        BigDecimal a = new BigDecimal(1);

        //BigDecimal(double) 创建一个具有参数所指定双精度值的对象
        BigDecimal b = new BigDecimal(0.1);
        //BigDecimal(long) 创建一个具有参数所指定长整数值的对象
        Long l = 6l;
        BigDecimal c = new BigDecimal(l);

        //BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象
        BigDecimal d = new BigDecimal("01");
    }

    /**
     * BigDecimal常用方法详解
     */
    @Test
    public void methodMain(){
        BigDecimal a = new BigDecimal("10");
        BigDecimal a1 = new BigDecimal("1000");
        BigDecimal b = new BigDecimal("0.1666");
        BigDecimal b1 = new BigDecimal("2.0");
        //add(BigDecimal)  BigDecimal对象中的值相加，返回BigDecimal对象
        BigDecimal c = a.add(b);
        System.out.println("相加后c的值为:"+c);
        //subtract(BigDecimal) BigDecimal对象中的值相减，返回BigDecimal对象
        c = a.subtract(b);
        System.out.println("相减后c的值为:"+c);
        //multiply(BigDecimal) BigDecimal对象中的值相乘，返回BigDecimal对象
        c = a.multiply(b);
        //保留2位小数
        String s1= c.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
        System.out.println("相乘后c的值为:"+c);
        System.out.println("相乘后c保留2位小数的值为:"+s1);
        //divide(BigDecimal)  BigDecimal对象中的值相除，返回BigDecimal对象
        BigDecimal c1 = a1.divide(b1);
        //相除并保留3位小数
        c = a.divide(b,3, BigDecimal.ROUND_HALF_UP);
        System.out.println("除以后c的值为:"+c);
        System.out.println("除以后c1的值为:"+c1);
        System.out.println("除以后c再intValue()的值为:"+c1.intValue());
        //toString() 将BigDecimal对象中的值转换成字符串
        String s =a.toString();
        System.out.println("toString()后s的值为:"+s);
        //doubleValue() 将BigDecimal对象中的值转换成双精度数
        double d = a.doubleValue();
        System.out.println("doubleValue()后d的值为:"+d);
        //floatValue() 将BigDecimal对象中的值转换成单精度数
        float f = a.floatValue();
        System.out.println("floatValue()后f的值为:"+f);
        //longValue() 将BigDecimal对象中的值转换成长整数
        long l =a.longValue();
        System.out.println("longValue()后l的值为:"+l);
        //intValue() 将BigDecimal对象中的值转换成整数
        int i = a.intValue();
        System.out.println("intValue()后i的值为:"+i);
    }

    /**
     * 比较大小
     */
    @Test
    public void compareTo(){
        //java中对BigDecimal比较大小一般用的是bigdemical的compareTo方法
        BigDecimal a = new BigDecimal("10");
        BigDecimal a1 = new BigDecimal("10");
        BigDecimal b = new BigDecimal("100");
        //int a = bigdemical.compareTo(bigdemical2)
        //a = -1,表示bigdemical小于bigdemical2；
        //a = 0,表示bigdemical等于bigdemical2；
        //a = 1,表示bigdemical大于bigdemical2
        int i = a.compareTo(b);
        System.out.println("比较的结果:"+i);
    }

    /**
     * 格式化
     */
    @Test
    public  void format(){
        NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用
        NumberFormat percent = NumberFormat.getPercentInstance();  //建立百分比格式化引用
        //四舍五入
        percent.setMaximumFractionDigits(3); //百分比小数点最多3位

        BigDecimal loanAmount = new BigDecimal("15000.48"); //贷款金额
        BigDecimal interestRate = new BigDecimal("0.0084444"); //利率
        BigDecimal interest = loanAmount.multiply(interestRate); //相乘

        System.out.println("贷款金额:\t" + currency.format(loanAmount));
        System.out.println("利率:\t" + percent.format(interestRate));
        System.out.println("利息:\t" + currency.format(interest));
    }

    /**
     * BigDecimal格式化保留2为小数，不足则补0：
     */
    @Test
    public void NumberFormat(){

        System.out.println(formatToNumber(new BigDecimal("3.435")));
        System.out.println(formatToNumber(new BigDecimal(0)));
        System.out.println(formatToNumber(new BigDecimal("0.00")));
        System.out.println(formatToNumber(new BigDecimal("0.001")));
        System.out.println(formatToNumber(new BigDecimal("0.006")));
        System.out.println(formatToNumber(new BigDecimal("0.206")));
        System.out.println(formatToNumber(new BigDecimal("6")));

    }

    /**
     * @desc 1.0~1之间的BigDecimal小数，格式化后失去前面的0,则前面直接加上0。
     * 2.传入的参数等于0，则直接返回字符串"0.00"
     * 3.大于1的小数，直接格式化返回字符串
     * @param obj 传入的小数
     * @return
     */
    public static String formatToNumber(BigDecimal obj) {
        DecimalFormat df = new DecimalFormat("#.00");
        if(obj.compareTo(BigDecimal.ZERO)==0) {
            return "0.00";
        }else if(obj.compareTo(BigDecimal.ZERO)>0&&obj.compareTo(new BigDecimal(1))<0){
            return "0"+df.format(obj).toString();
        }else {
            return df.format(obj).toString();
        }
    }

}
